/*
 * Copyright 2021-2022 Open Kunlun Technology <https://www.openkunlun.io>
 */

package io.openkunlun.scaladsl.serialization

import akka.actor.{ ExtendedActorSystem, Extension, ExtensionId, ExtensionIdProvider }
import org.json4s._
import org.json4s.jackson.Serialization

/**
 * @author ericxin.
 */
object JsonSerialization extends ExtensionId[JsonSerialization] with ExtensionIdProvider {
  override def lookup: ExtensionId[JsonSerialization] = JsonSerialization
  override def createExtension(system: ExtendedActorSystem) = new JsonSerialization(system)
}

class JsonSerialization(system: ExtendedActorSystem) extends Extension with DaprObjectSerialization {
  private val lock = new Object()
  implicit val formats = DefaultFormats

  var customerFormats: Seq[Serializer[_]] = Seq.empty

  override def serialize[T](serializable: T): Array[Byte] = {
    Serialization.write(serializable.asInstanceOf[AnyRef])(formats ++ customerFormats).getBytes("UTF-8")
  }

  /**
   *
   * @param bytes
   * @tparam T
   * @return
   */
  override def deserialize[T: Manifest](bytes: Array[Byte]): T = {
    Serialization.read[T](new String(bytes))(formats ++ customerFormats, manifest[T])
  }

  def addFormat(append: Serializer[_]) = {
    addFormats(append :: Nil)
  }

  def addFormats(appends: Seq[Serializer[_]]) = {
    lock.synchronized {
      customerFormats = this.customerFormats ++ appends
    }
  }
}